package com.gzsxy.esjy.common.base.util;

import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author xiaolong
 * @version 1.0
 * @description: TODO
 * @date 2021/12/28 9:46
 */
public class UriUtil {

    private static final Map<String, Pattern> PATTERN_MAP = new ConcurrentHashMap<>();
    /**
     * RESTFUL接口匹配  排除
     */
    private static final String REG_RESTFUL = "\\b(?!/)\\w+";

    /**
     * 匹配开头为/的一个或者无限次
     */
    private static Pattern prePattern = Pattern.compile("^/+");
    /**
     * \b 匹配单词字符[A-Za-z0-9]和非单词字符  \b(?!/)匹配不是/的字符串
     */
    private static Pattern restfulPattern = Pattern.compile("\\{\\b(?!/)\\w+\\}");

    /**
     * 过滤uri匹配 过滤1个或多个
     */
    private static final String REG_IGNORE = "\\S+";

    /**
     * 过滤uri匹配 过滤0个或多个
     */
    private static final String REG_IGNORE_ANY = "\\S*";





    public UriUtil(){
    }


    /**
     * @description: 判断url是否匹配成功
     * @param pattern 匹配路径
     * @param url 访问路径
     * @return
     */
    public static boolean isUrlMatches(String pattern,String url){
        Matcher m =null;

        url = dealUrl(url);
        if (PATTERN_MAP.containsKey(pattern)){
            m = ((Pattern) PATTERN_MAP.get(pattern)).matcher(url);
        } else {
            //将**替换为\\S+
            String regex = replaceAll(pattern, "**", REG_IGNORE);
            //将*替换为\\S*
            regex = replaceAll(regex,"*",REG_IGNORE_ANY);
            regex = replaceRestful(regex);
            regex = replacePre(regex);
            Pattern p = Pattern.compile(regex);
            m  = p.matcher(url);
            PATTERN_MAP.put(pattern,p);
        }
        return m.matches();
    }


    private static String dealUrl(String url){
        //如果字符串里面的值为null， “”， " "，为false；；/+  =》正则表达式--匹配/一个或者多个
        return StringUtils.hasText(url)? url.replaceAll("/+","/") :url;
    }


    /**
     * @description: 将指定的url中含有特点的 repStr值替换为repWith（使其成为符合正则表达式）
     * @param input  输入url
     * @param repStr  匹配值
     * @param repWith 替换值
     * @return
     */
    private static String replaceAll(String input, String repStr,String repWith){
        if (input == null) {
            return null;
        } else {
            StringBuffer buffer = new StringBuffer();
            int begin = 0;
            int index;
            //当如果匹配到**就替换为\\s+ ,采用正则表达式来表示
            for (boolean var5 = true; (index = input.indexOf(repStr,begin)) >= 0 && begin < input.length(); begin = index +repStr.length()){
                if (index != 0 && index != begin){
                    buffer.append(input.substring(begin,index)).append(repWith);
                } else {
                    buffer.append(repWith);
                }
            }
            //如果没有匹配到 **， 就采用默认的访问路径
            if (begin <input.length()){
                buffer.append(input.substring(begin));
            }
            return buffer.toString();
        }
    }


    private static String replaceRestful(String pattern){
        //find()方法是部分匹配，是查找输入串中与模式匹配的子串，如果该匹配的串有组还可以使用group()函数。 matcher.group()返回匹配到的子字符串
        Matcher matcher =  restfulPattern.matcher(pattern);
        while (matcher.find()){
            pattern = pattern.replace(matcher.group(),REG_RESTFUL);
        }
        return pattern;
    }


    /**
     * 替换uri前缀
     * @param pattern
     * @return
     */
    private static String replacePre(String pattern){
        Matcher matcher = prePattern.matcher(pattern);
        return matcher.find()?pattern.replaceFirst(matcher.group(),"/+") : "/+" + pattern;
    }


    /**
     * 匹配
     * @param patterns
     * @param uri
     * @return
     */
    public static boolean match(List<String> patterns, String uri){
        patterns.stream().anyMatch((pattern) ->{
            return isUrlMatches(pattern,uri);
        });
        return false;
    }

}
